﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Research.Kinect.Audio;
using Microsoft.Speech.AudioFormat;
using Microsoft.Speech.Recognition;
using System.Speech;
using System.Speech.Synthesis;


namespace SpeechRecognitionSynthesis
{
    class Program
    {
               
        static void Main(string[] args)
        {
            using (var source = new KinectAudioSource())
            {
                source.FeatureMode = true;
                source.AutomaticGainControl = false;// important to turn off
                source.SystemMode = SystemMode.OptibeamArrayOnly;//no AEC

                RecognizerInfo ri = GetKinectRecognizer();

                if (ri == null)
                {
                    Console.WriteLine("Could not find speech recognizer.");
                    return;
                }
                Console.WriteLine("using: {0}", ri.Name);

                using (var sre = new SpeechRecognitionEngine(ri.Id))
                {
                    Choices commands = new Choices("light on", "light off", "fan on", "fan off",
                       "cricket score", "whats the news","what are my reminders for today","how is the weather","what is the time","what day is it");

                    GrammarBuilder gb = new GrammarBuilder();
                    gb.Append("alice");
                    gb.Append(commands);
                   

                    Grammar g = new Grammar(gb);

                    sre.LoadGrammar(g);


                    
                    sre.SpeechRecognized += SreSpeechRecognized;
                   

                    using (Stream s = source.Start())
                    {
                        sre.SetInputToAudioStream(s, new SpeechAudioFormatInfo(
                            EncodingFormat.Pcm, 16000, 16, 1, 32000, 2, null));

                    Console.WriteLine("recognizing PRESS ENTER to stop");
                        sre.RecognizeAsync(RecognizeMode.Multiple);
                        Console.ReadLine();
                        Console.WriteLine("stopping recognizer.....");
                        sre.RecognizeAsyncStop();
                        
                    }
                }
            }
        }

        private static RecognizerInfo GetKinectRecognizer()
        {
            Func<RecognizerInfo, bool> matchingFunc = r =>
            {
                string value;
                r.AdditionalInfo.TryGetValue("Kinect", out value);
                return "True".Equals(value, StringComparison.InvariantCultureIgnoreCase) && "en-US".Equals(r.Culture.Name, StringComparison.InvariantCultureIgnoreCase);
            };
            return SpeechRecognitionEngine.InstalledRecognizers().Where(matchingFunc).FirstOrDefault();
        }


        static void SreSpeechRecognized(object sender, SpeechRecognizedEventArgs e)
        {
            SpeechSynthesizer s = new SpeechSynthesizer();
            Console.WriteLine("\nSpeech Recognized: \t{0}" + e.Result.Confidence, e.Result.Text);
            if (e.Result.Confidence < 0.85)
                return;

            switch (e.Result.Text)
            {
                case "alice light on": 
                    light(1);
                    s.Speak("the light has been turned on.");
                    break;
                case "alice light off": 
                    light(0);
                    s.Speak("the light has been turned off.");
                    break;
                case "alice fan on": 
                    fan(1);
                    s.Speak("the fan has been turned on.");
                    break;
                case "alice fan off": 
                    fan(0);
                    s.Speak("the fan has been turned off.");
                    break;
                case "alice cricket score":
                    cricket();
                    break;
                case "alice whats the news":
                    news();
                    break;
                case "alice what are my reminders":
                    reminders();
                    break;
                case "alice how is the weather":

                Conditions conditions = new Conditions();
                conditions = Weather.GetCurrentConditions();

                if (conditions != null)
                {
                    s.Speak("Sir the weather here is " + conditions.Condition + "the temperature is " + conditions.TempC +
                        "degree celsius" + "the humidity is" + conditions.Humidity + "the wind is blowing at a speed of" + conditions.Wind);
                                       
                }
                else
                {
                    s.Speak("sorry Sir there was an error processing your request. I think you should check your internet connection.");
                }

                    List<Conditions> condition = new List<Conditions>();
                    condition = Weather.GetForecast();

                    if (condition != null)
                    {
                        foreach (Conditions c in condition)
                        {
                            s.Speak("on" + c.DayOfWeek + "it would be" + c.Condition + "the high temperature would be" + c.High + 
                                "the lowest temperature would be" + c.Low);
                           
                        }
                    }
                   
                    break;
                case "alice what is the time":

                    s.Speak(DateTime.Now.ToShortTimeString());                    

                    break;
                case "alice what day is it":
                    DateTime dt;
                    dt = DateTime.Now;
                   s.Speak(dt.DayOfWeek.ToString());

                   break;               
              default:
                   
                    break;
            }
        }

        static void light(int val)
        {
            Console.WriteLine("\nSpeech Recognized:light ");
        }

        static void fan(int val)
        {
            Console.WriteLine("\nSpeech Recognized: fan");
        }

        static void cricket()
        {
            Console.WriteLine("\nSpeech Recognized: cricket");
        }

        static void news()
        {
            Console.WriteLine("\nSpeech Recognized: news");
        }

        static void reminders()
        {
            Console.WriteLine("\nSpeech Recognized: reminders");
        }

       
       
    }
}
